package com.ihrm.atte;


import com.ihrm.common.shiro.realm.IhrmRealm;
import com.ihrm.common.shiro.session.CustomSessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.shiro.mgt.SecurityManager;

import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfiguration {
    
    @Value("${spring.redis.host}")
    private String host;
    @Value("${spring.redis.port}")
    private int port;
    
    
    /**
     * 创建realm
     */
    @Bean
    public IhrmRealm getRealm(){
        return new IhrmRealm();
    }
    
    /**
     * 创建安全管理器
     */
    @Bean
    public SecurityManager getSecurityManager(IhrmRealm realm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(realm);
    
        /**
         * 将自定义的会话管理器注册到安全管理器中
         */
        securityManager.setSessionManager(sessionManager());
        /**
         * 将自定义的redis缓存管理器注册到安全管理器中
         */
        securityManager.setCacheManager(cacheManager());
        
        return securityManager;
    }
    
    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){
    
        /**
         * 创建过滤工厂
         */
        ShiroFilterFactoryBean filterFactory = new ShiroFilterFactoryBean();
    
        /**
         * 设置安全过滤器
         */
        filterFactory.setSecurityManager(securityManager);
    
        /**
         * 通用配置(跳转登录页面，未授权跳转的页面)
         */
        /**
         * 跳转url地址
         */
        filterFactory.setLoginUrl("/autherror?code=1");
        /**
         * 未授权的url
         */
        filterFactory.setUnauthorizedUrl("/autherror?code=2");
    
        /**
         * 设置过滤器集合
         */
        Map<String,String> filterMap=new LinkedHashMap<>();
    
        /**
         * anno 匿名访问
         */
        filterMap.put("/sys/login","anno");
        filterMap.put("/sys/city/**","anon");
        filterMap.put("/sys/faceLogin/**","anon");
        filterMap.put("/autherror","anon");
    
        /**
         * 注册
         * authc--认证之后访问(登录)
         */
        filterMap.put("/**","authc");
    
        /**
         * perms -- 具有某种权限(使用注解配置授权)
         */
        filterFactory.setFilterChainDefinitionMap(filterMap);
    
        return filterFactory;
    }
    
    /**
     * 开启对shiro注解的支持
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
        
    }
    
    
    /**
     * redis控制器，操作redis
     */
    public RedisManager redisManager(){
        RedisManager redisManager = new RedisManager();
        redisManager.setHost(host);
        redisManager.setPort(port);
        return redisManager;
    }
    
    /**
     * sessionDao
     */
    public RedisSessionDAO redisSessionDAO(){
        RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
        redisSessionDAO.setRedisManager(redisManager());
        return redisSessionDAO;
    }
    
    /**
     * 会话管理器
     */
    public DefaultWebSessionManager sessionManager(){
        CustomSessionManager sessionManager = new CustomSessionManager();
        sessionManager.setSessionDAO(redisSessionDAO());
        
        /**
         * 禁用url重写
         */
        sessionManager.setSessionIdUrlRewritingEnabled(false);
        return sessionManager;
    }
    
    /**
     * 缓存管理器
     */
    public RedisCacheManager cacheManager(){
        RedisCacheManager redisCacheManager = new RedisCacheManager();
        redisCacheManager.setRedisManager(redisManager());
        return redisCacheManager;
    }

}
